/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.action;

import cn.easyplatform.entities.BaseEntity;
import cn.easyplatform.entities.beans.LogicBean;
import cn.easyplatform.entities.beans.ResourceBean;
import cn.easyplatform.entities.beans.api.ApiBean;
import cn.easyplatform.entities.beans.batch.BatchBean;
import cn.easyplatform.entities.beans.bpm.BpmBean;
import cn.easyplatform.entities.beans.list.ListBean;
import cn.easyplatform.entities.beans.page.PageBean;
import cn.easyplatform.entities.beans.report.JasperReportBean;
import cn.easyplatform.entities.beans.report.JxlsReport;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.entities.beans.task.TaskBean;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.entity.CheckCmd;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.StudioUtil;
import cn.easyplatform.studio.vos.LinkVo;
import cn.easyplatform.studio.vos.LoginUserVo;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.type.EntityType;
import cn.easyplatform.type.SubType;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.*;


/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class CreateAction extends AbstractAction implements
        EventListener<Event> {
    private North north;

    private Combobox type;

    private Row reportTypeRow;

    private Combobox reportType;

    private Html content;

    private Textbox id;

    private Label modelId;

    private Textbox name;

    private Textbox desp;

    private Button ok;

    private Div createLinkDiv;

    private Checkbox switchbox;

    private EntityType regularEntityType;

    private SubType regularSubType;

    private OnSuccessListener createLinkListener;

    private LinkVo updateVo;

    private OnSuccessListener updateLinkListener;

    private OnCreateListener createListener;

    private Label selectEntityName;

    public interface OnSuccessListener {
        void getEntity(LinkVo linkVo);

        void saveEntity(BaseEntity entity);

        void closeWindow();
    }

    public interface OnCreateListener {
        void closeWindow();
    }

    /**
     * @param workbench
     */
    public CreateAction(WorkbenchController workbench, OnCreateListener createListener) {
        super(workbench);
        if (null != createListener) {
            this.createListener = createListener;
        }
    }

    public CreateAction(WorkbenchController workbench, EntityType regularEntityType, SubType regularSubType, OnCreateListener createListener) {
        super(workbench);
        this.regularEntityType = regularEntityType;
        this.regularSubType = regularSubType;
        if (null != createListener) {
            this.createListener = createListener;
        }
    }

    public CreateAction(WorkbenchController workbench, OnSuccessListener createLinkListener) {
        super(workbench);
        if (null != createLinkListener) {
            this.createLinkListener = createLinkListener;
        }
    }

    public CreateAction(WorkbenchController workbench, LinkVo updateVo, OnSuccessListener updateLinkListener) {
        super(workbench);
        if (null != updateLinkListener) {
            this.updateLinkListener = updateLinkListener;
            this.updateVo = updateVo;
        }
    }

    @Override
    public void on() {
        //加载页面
        Component c = Executions.createComponents(
                "~./include/wizards/create.zul", null, null);
        north = (North) c.getFellow("create_north_choose");

        //参数类型 下拉框
        type = (Combobox) c.getFellow("create_combobox_type");
        LoginUserVo loginUserVo = Contexts.getUser();
        for (Comboitem ci : type.getItems()) {
            String name = ci.getValue().toString().toLowerCase() + "Add";
            ci.setDisabled(!loginUserVo.isAuthorized(name));
        }
        type.setSelectedIndex(0);
        type.addEventListener(Events.ON_SELECT, this);
        reportTypeRow = (Row) c.getFellow("create_report_subType_row");
        //报表类型下拉框
        reportType = (Combobox) c.getFellow("create_report_subType");
        for (Comboitem ci : reportType.getItems()) {
            String name = "reportAdd";
            ci.setDisabled(!loginUserVo.isAuthorized(name));
        }
        reportType.setSelectedIndex(0);
        reportType.addEventListener(Events.ON_SELECT, this);

        //说明文字
        content = (Html) c.getFellow("content");
        content.setContent(Labels.getLabel("entity.page.desp"));
        id = (Textbox) c.getFellow("create_textbox_entityid");
        modelId = (Label) c.getFellow("create_label_modelId");
        if (StudioApp.isCloudDeployment()) {
            modelId.setVisible(true);
            modelId.setValue(Contexts.getProject().getId() + "_");
        }
        id.addEventListener(Events.ON_CHANGE, this);
        name = (Textbox) c.getFellow("create_textbox_entityname");
        desp = (Textbox) c.getFellow("create_textbox_entitydesp");
        ok = (Button) c.getFellow("create_button_ok");
        ok.addEventListener(Events.ON_CLICK, this);
        createLinkDiv = (Div) c.getFellow("create_div_function_createLink");
        switchbox = (Checkbox) c.getFellow("create_switchbox_function_isNew");
        switchbox.setChecked(true);

        if (null != updateLinkListener) {
            //更改Link(一定为未创建参数)。显示开关，按钮为ok
            createLinkDiv.setVisible(false);
            String entityType = updateVo.getEntityType();
            String entitySubType = updateVo.getEntitySubType();
            chooseType(entityType, entitySubType);
            id.setDisabled(true);
            id.setValue(updateVo.getEntityId());
            desp.setValue(updateVo.getEntityDesp());
            name.setValue(updateVo.getEntityName());
            ((Window) c).setTitle(Labels.getLabel("entity.diagram.update.entity"));
        } else if (null != createLinkListener) {
            //创建Link。默认显示开关，选择未建成，按钮为ok
            createLinkDiv.setVisible(false);
        }

        ((Window) c).addEventListener(Events.ON_CLOSE, this);
        if (regularEntityType != null) {
            String entityType = null;
            switch (regularEntityType) {
                case TASK:
                    entityType = EntityType.TASK.getName();
                    break;
                case PAGE:
                    entityType = EntityType.PAGE.getName();
                    break;
                case DATALIST:
                    entityType = EntityType.DATALIST.getName();
                    break;
                case TABLE:
                    entityType = EntityType.TABLE.getName();
                    break;
                case BATCH:
                    entityType = EntityType.BATCH.getName();
                    break;
                case BPM:
                    entityType = EntityType.BPM.getName();
                    break;
                case LOGIC:
                    entityType = EntityType.LOGIC.getName();
                    break;
                case DATASOURCE:
                    entityType = EntityType.DATASOURCE.getName();
                    break;
                case API:
                    entityType = EntityType.API.getName();
                    break;
                case REPORT:
                    entityType = EntityType.REPORT.getName();
                    break;
                case RESOURCE:
                    entityType = EntityType.RESOURCE.getName();
                    break;
                case PROJECT:
                    entityType = EntityType.PROJECT.getName();
                    break;
            }
            String subType = null;
            if (regularSubType != null) {
                switch (regularSubType) {
                    case JOB:
                        subType = SubType.JOB.getName();
                        break;
                    case Main:
                        subType = SubType.Main.getName();
                        break;
                    case JXLS:
                        subType = SubType.JXLS.getName();
                        break;
                    case CACHE:
                        subType = SubType.CACHE.getName();
                        break;
                    case JASPER:
                        subType = SubType.JASPER.getName();
                        break;
                }
            }

            chooseType(entityType, subType);

        }
    }

    @Override
    public void onEvent(Event event) throws Exception {
        Component c = event.getTarget();

        if (c == id) {
            String entityId = "";
            if (StudioApp.isCloudDeployment()) {
                entityId = modelId.getValue() + id.getValue().trim();
            } else {
                entityId = id.getValue().trim();
            }
            if (StudioApp.execute(new CheckCmd(entityId))) {
                Clients.wrongValue(id, Labels.getLabel("entity.exists.id",
                        new String[]{entityId}));
                id.setFocus(true);
            }
        } else if (c == type) {
            String value = type.getSelectedItem().getValue();
            content.setContent(Labels.getLabel("entity." + value.toLowerCase()
                    + ".desp"));
            if (type.getValue().equalsIgnoreCase("报表")) {
                reportTypeRow.setVisible(true);
              //  north.setSize("280px");
            } else {
                reportTypeRow.setVisible(false);
                //north.setSize("230px");
            }
        } else if (c == ok) {
            String entityId = "";
            if (StudioApp.isCloudDeployment()) {
                entityId = modelId.getValue() + id.getValue().trim();
            } else {
                entityId = id.getValue().trim();
            }
            if (id.getValue().trim().equals("")) {
                id.setFocus(true);
                throw new WrongValueException(id, Labels.getLabel(
                        "message.no.empty",
                        new Object[]{Labels.getLabel("entity.id")}));
            }
            if (name.getText().trim().equals("")) {
                name.setFocus(true);
                throw new WrongValueException(name, Labels.getLabel(
                        "message.no.empty",
                        new Object[]{Labels.getLabel("entity.name")}));
            }
            String tp = type.getSelectedItem().getValue();
            if (tp.equals("Table")) {
                if (Strings.isBlank(id.getValue().trim()) == false  && id.getValue().trim().matches("^[a-zA-Z]\\S*$") == false) {
                    id.setFocus(true);
                    throw new WrongValueException(id, Labels.getLabel(
                            "entity.table.field.name.is.char"));
                }
            }
            if (StudioApp.execute(new CheckCmd(entityId)) && null == updateLinkListener) {
                Clients.wrongValue(id, Labels.getLabel("entity.exists.id",
                        new String[]{entityId}));
                id.setFocus(true);
                return;
            }
            if (null != createLinkListener) {
                //创建关系，并且选择未创建参数
                if (switchbox.isChecked() == false) {
                    createLinkListener.getEntity(createLineVo(LinkVo.VIRTUALSTATUS));
                    type.getRoot().detach();
                    createLinkListener.closeWindow();
                    return;
                }
            } else if (null != updateLinkListener) {
                //修改关系，并且未创建参数
                if (switchbox.isChecked() == false) {
                    LinkVo vo = updateLineVo();
                    updateLinkListener.getEntity(vo);
                    type.getRoot().detach();
                    updateLinkListener.closeWindow();
                    return;
                }
            }

            //当选中非页面参数，默认样式为空
            onCreate();
        } else if (event.getName().equals(Events.ON_CLOSE)) {
            if (createLinkListener != null)
                createLinkListener.closeWindow();
            else if (updateLinkListener != null)
                updateLinkListener.closeWindow();
            else if (createListener != null)
                createListener.closeWindow();
        }
    }

    private void chooseType(String entityType, String entitySubType) {
        String typeValue = StudioUtil.getSringWithEntityType(entityType, entitySubType);
        type.setValue(typeValue);
        content.setContent(Labels.getLabel("entity." + entityType.toLowerCase()
                + ".desp"));
        if (EntityType.REPORT.getName().equals(entityType)) {
            reportTypeRow.setVisible(true);
           // north.setSize("280px");
            reportType.setDisabled(true);
            if (SubType.JASPER.getName().equals(entitySubType)) {
                reportType.setValue("Jasper");
            } else if (SubType.JXLS.getName().equals(entitySubType)) {
                reportType.setValue("excel");
            } else
                reportType.setDisabled(false);
        } else {
            reportTypeRow.setVisible(false);
           // north.setSize("230px");
        }

        type.setDisabled(true);
    }

    private void onCreate() {
        String tp = type.getSelectedItem().getValue();
        BaseEntity entity = null;
        if (tp.equals("Page"))
            entity = new PageBean();
        else if (tp.equals("Task"))
            entity = new TaskBean();
        else if (tp.equals("Datalist")) {
            entity = new ListBean();
        } else if (tp.equals("Table"))
            entity = new TableBean();
        else if (tp.equals("Logic"))
            entity = new LogicBean();
        else if (tp.equals("Report")) {
            if (reportType.getSelectedItem().getValue().equals("Jasper")) {
                entity = new JasperReportBean();
            } else if (reportType.getSelectedItem().getValue().equals("Jxls")) {
                entity = new JxlsReport();
            }
            entity.setSubType((String) reportType.getSelectedItem().getValue());
        } else if (tp.equals("Batch"))
            entity = new BatchBean();
        else if (tp.equals("Bpm"))
            entity = new BpmBean();
        else if (tp.equals("Api"))
            entity = new ApiBean();
        else {
            entity = new ResourceBean();
            if (tp.equals("Resource"))
                entity.setSubType(SubType.CACHE.getName());
            else
                entity.setSubType(SubType.JOB.getName());
            tp = EntityType.RESOURCE.getName();
        }
        entity.setId(StudioApp.isCloudDeployment() ? modelId.getValue() + id.getValue().trim() : id.getValue().trim());
        entity.setType(tp);
        entity.setName(name.getText());
        entity.setDescription(desp.getText());
        type.getRoot().detach();
        if (createLinkListener != null)
            createLinkListener.closeWindow();
        else if (updateLinkListener != null)
            updateLinkListener.closeWindow();
        else if (createListener != null)
            createListener.closeWindow();

        OnSuccessListener currentListener = updateVo == null ? createLinkListener : updateLinkListener;
        workbench.createEditor(entity, 'C', currentListener);
    }

    private LinkVo createLineVo(String status) {
        String typeStr = type.getSelectedItem().getValue();
        String subTypeStr = null;
        if (EntityType.RESOURCE.getName().equals(typeStr)) {
            typeStr = EntityType.RESOURCE.getName();
            subTypeStr = SubType.CACHE.getName();
        } else if (EntityType.REPORT.getName().equals(typeStr)) {
            if (reportType.getSelectedItem().getValue().equals("Jasper")) {
                subTypeStr = SubType.JASPER.getName();
            } else if (reportType.getSelectedItem().getValue().equals("Jxls")) {
                subTypeStr = SubType.JXLS.getName();
            }
        } else if (SubType.JOB.getName().equals(typeStr)) {
            typeStr = EntityType.RESOURCE.getName();
            subTypeStr = SubType.JOB.getName();
        }
        LinkVo linkVo = new LinkVo(StudioApp.isCloudDeployment() ? modelId.getValue() + id.getValue().trim() : id.getValue().trim(), null, name.getValue().trim(), typeStr,
                subTypeStr, desp.getValue().trim(), null, null, null,
                null, status);
        return linkVo;
    }


    private LinkVo updateLineVo() {
        String typeStr = type.getSelectedItem().getValue();
        String subTypeStr = null;
        if (EntityType.RESOURCE.getName().equals(typeStr)) {
            typeStr = EntityType.RESOURCE.getName();
            subTypeStr = SubType.CACHE.getName();
        } else if (EntityType.REPORT.getName().equals(typeStr)) {
            if (reportType.getSelectedItem().getValue().equals("Jasper")) {
                subTypeStr = SubType.JASPER.getName();
            } else if (reportType.getSelectedItem().getValue().equals("Jxls")) {
                subTypeStr = SubType.JXLS.getName();
            }
        } else if (SubType.JOB.getName().equals(typeStr)) {
            typeStr = EntityType.RESOURCE.getName();
            subTypeStr = SubType.JOB.getName();
        }
        LinkVo vo = new LinkVo(updateVo.getEntityId(), updateVo.getChildrenEntityId(), name.getValue().trim(),
                typeStr, subTypeStr, desp.getValue().trim(), updateVo.getCreateDate(), updateVo.getUpdateDate(),
                updateVo.getCreateUser(), updateVo.getUpdateUser(), updateVo.getStatus());
        return vo;
    }
}
